package org.activemonitoring.datastore.rest.client;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

import org.activemonitoring.domain.Measures;
import org.apache.commons.lang.exception.ExceptionUtils;

@Provider
@Produces("text/xml")
public class MeasuresWriter implements MessageBodyWriter<Measures> {

    private JAXBContext context;

    public MeasuresWriter() throws JAXBException {
        super();
        this.context = createJaxbContext();
    }

    protected JAXBContext createJaxbContext() throws JAXBException {
        return JAXBContext.newInstance(Measures.class);
    }

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        boolean accept = type.equals(Measures.class) && mediaType.equals(MediaType.TEXT_XML_TYPE);
        return accept;
    }

    @Override
    public void writeTo(Measures measures, Class<?> type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
            throws IOException, WebApplicationException {
        try {
            this.context.createMarshaller().marshal(measures, entityStream);
        } catch (JAXBException e) {
            Throwable t = ExceptionUtils.getRootCause(e);
            throw new IOException(t);
        }
    }

    @Override
    public long getSize(Measures measures, Class<?> type, Type genericType, Annotation[] annotations,
            MediaType mediaType) {
        // Can't guess the output content length
        return -1;
    }
}
